home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / TURBOPASCAL WIN / RWDEMOS.PAK / RWPWND.PAS < prev    next >
Pascal/Delphi Source File  |  1992-06-08  |  29KB  |  1,153 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Pascal for Windows                     }
  4. {   Resource Workshop Demo                       }
  5. {   Copyright (c) 1992 by Borland International  }
  6. {                                                }
  7. {************************************************}
  8.  
  9. unit RWPWnd;
  10.  
  11. interface
  12.  
  13. uses RWPDlgs, WinProcs, WinTypes, WObjects, Strings, StdDlgs, RWPDemoC, WinDOS;
  14.  
  15. const
  16.   OpenEditWindows: Word = 0;
  17.   OpenWindows: Word = 0;
  18.  
  19. type
  20.   PBaseMDIChildWindow = ^TBaseMDIChildWindow;
  21.   TBaseMDIChildWindow = object(TWindow)
  22.     TheMenu: HMenu;
  23.     constructor Init(aParent: PWindowsObject; ATitle: PChar);
  24.     destructor Done; virtual;
  25.     function GetPopupMenu: HMenu; virtual;
  26.     function GetPopupTitle: PChar; virtual;
  27.     procedure SetEditPopup(Style: Word);
  28.     procedure SetWindowPopup(Style: Word);
  29.     procedure SetupWindow; virtual;
  30.     procedure WMMDIActivate(var Msg: TMessage); virtual wm_MDIActivate;
  31.     procedure WMRButtonDown(var Msg: TMessage); virtual wm_RButtonUp;
  32.   end;
  33.  
  34.   { TDocument }
  35.   PDocument = ^TDocument;
  36.   TDocument = object(TBaseMDIChildWindow)
  37.     Changed: Boolean;
  38.     FileName: PChar;
  39.     IsNewFile: Boolean;
  40.  
  41.     constructor Init(AParent: PWindowsObject; AFileName: PChar);
  42.     constructor Load(var S: TStream);
  43.     destructor Done; virtual;
  44.     function CanClear: Boolean; virtual;
  45.     function CanClose: Boolean; virtual;
  46.     procedure ClearModify;
  47.     procedure ClearWindow; virtual;
  48.     procedure CMFileSave(var Msg: TMessage); virtual cm_First + cm_Save;
  49.     procedure CMFileSaveAs(var Msg: TMessage); virtual cm_First + cm_SaveAs;
  50.     function GetTitlePrefix: PChar; virtual;
  51.     function IsModified: Boolean; virtual;
  52.     procedure Read; virtual;
  53.     function Save: Boolean; virtual;
  54.     function SaveAs: Boolean; virtual;
  55.     procedure SetFileName(AFileName: PChar);
  56.     procedure SetupWindow; virtual;
  57.     procedure Store(var S: TStream);
  58.     procedure Write; virtual;
  59.   end;
  60.  
  61.   { TEditWindow  }
  62.   PEditWindow = ^TEditWindow;
  63.   TEditWindow = object(TDocument)
  64.     Editor: PEdit;
  65.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  66.     constructor Load(var S: TStream);
  67.     destructor Done; virtual;
  68.     procedure ClearModify; virtual;
  69.     procedure ClearWindow; virtual;
  70.     function  GetTitlePrefix: PChar; virtual;
  71.     function IsModified: Boolean; virtual;
  72.     procedure Read; virtual;
  73.     procedure Store(var S: TStream);
  74.     procedure WMSize(var Msg: TMessage); virtual wm_First + wm_Size;
  75.     procedure WMSetFocus(var Msg: TMessage); virtual wm_First + wm_SetFocus;
  76.     procedure Write; virtual;
  77.   end;
  78.  
  79.  
  80. type
  81.   PGraphObject = ^TGraphObject;
  82.   TGraphObject = object(TObject)
  83.     X1, Y1, X2, Y2: Integer;
  84.     TheColor: TColorRef;
  85.     ThePen: THandle;
  86.     OldPen: THandle;
  87.     constructor Init(R: TRect; AColor: TColorRef);
  88.     constructor Load(var S: TStream);
  89.     procedure Assign(R: TRect);
  90.     procedure Draw(HandleDC: HDC); virtual;
  91.     procedure DrawRect(HandleDC: HDC; R: TRect);
  92.     procedure EndDraw(HandleDC: HDC);
  93.     procedure Store(var S: TStream);
  94.   end;
  95.  
  96.   PRectangle = ^TRectangle;
  97.   TRectangle = object(TGraphObject)
  98.     procedure Draw(HandleDC: HDC); virtual;
  99.   end;
  100.  
  101.   PCircle = ^TCircle;
  102.   TCircle = object(TGraphObject)
  103.     procedure Draw(HandleDC: HDC); virtual;
  104.   end;
  105.  
  106. const
  107.   ShapeCircle = 1;
  108.   ShapeRectangle = 2;
  109.  
  110. type
  111.   PGraphWindow = ^TGraphWindow;
  112.   TGraphWindow = object(TDocument)
  113.     ButtonDown: Boolean;
  114.     CurrentShape: PGraphObject;
  115.     HandleDC: HDC;
  116.     MenuShape: Integer;
  117.     MenuColor: TColorRef;
  118.     OldROP: Word;
  119.     Rect: TRect;
  120.     TheShapes: PCollection;
  121.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  122.     destructor Done; virtual;
  123.     procedure Clear; virtual;
  124.     procedure CMBlue(var Msg: TMessage); virtual cm_First + cm_Blue;
  125.     procedure CMCircle(var Msg: TMessage); virtual cm_First + cm_Circle;
  126.     procedure CMClear(var Msg: TMessage); virtual cm_First + cm_ClearShape;
  127.     procedure CMGreen(var Msg: TMessage); virtual cm_First + cm_Green;
  128.     procedure CMRectangle(var Msg: TMessage); virtual cm_First + cm_Rectangle;
  129.     procedure CMRed(var Msg: TMessage); virtual cm_First + cm_Red;
  130.     function GetPopupMenu: HMenu; virtual;
  131.     function GetPopupTitle: PChar; virtual;
  132.     function GetTitlePrefix: PChar; virtual;
  133.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  134.     procedure Read; virtual;
  135.     procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown;
  136.     procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp;
  137.     procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove;
  138.     procedure Write; virtual;
  139.   end;
  140.  
  141. type
  142.   PPointCollection = ^TPointCollection;
  143.   TPointCollection = object(TCollection)
  144.     destructor Done; virtual;
  145.     function GetItem(var S: TStream): Pointer; virtual;
  146.     procedure PutItem(var S: TStream; Item: Pointer); virtual;
  147.   end;
  148.  
  149. type
  150.   PLine = ^TLine;
  151.   TLine = object(TObject)
  152.     X,Y: Integer;
  153.     LineColor: TColorRef;
  154.     PointCollection: PPointCollection;
  155.     LineThickness: Byte;
  156.     constructor Init(AColor: TColorRef; AThickness: Byte);
  157.     constructor Load(var S: TStream);
  158.     destructor Done; virtual;
  159.     procedure Store(var S: TStream);
  160.   end;
  161.  
  162. type
  163.   PScribbleWindow = ^TScribbleWindow;
  164.   TScribbleWindow = object(TDocument)
  165.     ButtonDown: Boolean;
  166.     CurrentLine: PLine;
  167.     HandleDC: HDC;
  168.     LineCollection: PCollection;
  169.     MenuColor: TColorRef;
  170.     MenuThickness: Byte;
  171.     OldPen: THandle;
  172.  
  173.     constructor Init(aParent: PWindowsObject; ATitle: PChar);
  174.     constructor Load(var S: TStream);
  175.     destructor Done; virtual;
  176.     procedure Clear; virtual;
  177.     procedure CMBlue(var Msg: TMessage); virtual cm_First + cm_Blue;
  178.     procedure CMClear(var Msg: TMessage); virtual cm_First + cm_ClearShape;
  179.     procedure CMGreen(var Msg: TMessage); virtual cm_First + cm_Green;
  180.     procedure CMNormal(var Msg: TMessage); virtual cm_First + cm_Normal;
  181.     procedure CMRed(var Msg: TMessage); virtual cm_First + cm_Red;
  182.     procedure CMThick(var Msg: TMessage); virtual cm_First + cm_Thick;
  183.     procedure CMThin(var Msg: TMessage); virtual cm_First + cm_Thin;
  184.     function GetPopupMenu: HMenu; virtual;
  185.     function GetPopupTitle: PChar; virtual;
  186.     function GetTitlePrefix: PChar; virtual;
  187.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  188.     procedure Read; virtual;
  189.     procedure Store(var S: TStream); virtual;
  190.     procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown;
  191.     procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp;
  192.     procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove;
  193.     procedure Write; virtual;
  194.   end;
  195.  
  196. implementation
  197.  
  198. function Min(a, b: Word): Word;
  199. begin
  200.   if a < b then Min := a
  201.   else Min := b;
  202. end;
  203.  
  204. function Max(a, b: Word): Word;
  205. begin
  206.   if a > b then Max := a
  207.   else Max := b;
  208. end;
  209.  
  210. {---------------- TBaseMDIChildWindow implementation ------------------}
  211.  
  212. constructor TBaseMDIChildWindow.Init(aParent: PWindowsObject; ATitle: PChar);
  213. begin
  214.   TWindow.Init(aParent, ATitle);
  215.   TheMenu := 0;
  216. end;
  217.  
  218. procedure TBaseMDIChildWindow.SetupWindow;
  219. begin
  220.   TWindow.SetupWindow;
  221.   if (OpenWindows = 0) then
  222.     SetWindowPopup(mf_Enabled);
  223.   Inc(OpenWindows);
  224. end;
  225.  
  226. destructor TBaseMDIChildWindow.Done;
  227. begin
  228.   TWindow.Done;
  229.   Dec(OpenWindows);
  230.   if OpenWindows = 0 then
  231.     SetWindowPopup(mf_Disabled or mf_Grayed);
  232. end;
  233.  
  234.  
  235. function TBaseMDIChildWindow.GetPopupMenu: HMenu;
  236. begin
  237.   GetPopupMenu := 0;
  238. end;
  239.  
  240. function TBaseMDIChildWindow.GetPopupTitle: PChar;
  241. begin
  242.   GetPopupTitle := nil;
  243. end;
  244.  
  245. procedure TBaseMDIChildWindow.SetEditPopup(Style: Word);
  246. var
  247.   AMenu: HMenu;
  248. begin
  249.   if Application^.MainWindow^.HWindow <> 0 then
  250.   begin
  251.     AMenu := GetMenu(Application^.MainWindow^.HWindow);
  252.     if AMenu <> 0 then
  253.     begin
  254.       EnableMenuItem(AMenu, cm_EditUndo, mf_ByCommand or Style);
  255.       EnableMenuItem(AMenu, cm_EditCut, mf_ByCommand or Style);
  256.       EnableMenuItem(AMenu, cm_EditCopy, mf_ByCommand or Style);
  257.       EnableMenuItem(AMenu, cm_EditPaste, mf_ByCommand or Style);
  258.       EnableMenuItem(AMenu, cm_EditClear, mf_ByCommand or Style);
  259.       EnableMenuItem(AMenu, cm_EditDelete, mf_ByCommand or Style);
  260.    end;
  261.   end;
  262. end;
  263.  
  264. procedure TBaseMDIChildWindow.SetWindowPopup(Style: Word);
  265. var
  266.   AMenu: HMenu;
  267. begin
  268.   if Application^.MainWindow^.HWindow <> 0 then
  269.   begin
  270.     AMenu := GetMenu(Application^.MainWindow^.HWindow);
  271.     if AMenu <> 0 then
  272.     begin
  273.       EnableMenuItem(AMenu, cm_CloseChildren, mf_ByCommand or Style);
  274.       EnableMenuItem(AMenu, cm_TileChildren, mf_ByCommand or Style);
  275.       EnableMenuItem(AMenu, cm_CascadeChildren, mf_ByCommand or Style);
  276.       EnableMenuItem(AMenu, cm_ArrangeIcons, mf_ByCommand or Style);
  277.       EnableMenuItem(AMenu, cm_Save, mf_ByCommand or Style);
  278.       EnableMenuItem(AMenu, cm_SaveAs, mf_ByCommand or Style);
  279.       EnableMenuItem(AMenu, cm_Print, mf_ByCommand or Style);
  280.     end;
  281.   end;  
  282. end;
  283.  
  284.  
  285. procedure TBaseMDIChildWindow.WMMDIActivate(var Msg: TMessage);
  286. begin
  287.   DefWndProc(Msg);
  288.   if Typeof(Self) = TypeOf(TEditWindow) then
  289.     SetEditPopup(mf_Enabled)
  290.   else
  291.     SetEditPopup(mf_Grayed);
  292. end;
  293.  
  294. procedure TBaseMDIChildWindow.WMRButtonDown(var Msg: TMessage);
  295. var
  296.   AMenu: HMenu;
  297.   AName: PChar;
  298. begin
  299.   AMenu := CreatePopupMenu;
  300.   AName := GetPopupTitle;
  301.  
  302.   if AName <> nil then
  303.   begin
  304.     AppendMenu(AMenu, mf_Popup, GetPopupMenu, AName);
  305.     ClientToScreen(HWindow, MakePoint(Msg.LParam));
  306.     TrackPopupMenu(AMenu, 0, Msg.LParamLo, Msg.LParamHi, 0, HWindow, nil);
  307.     DestroyMenu(AMenu);
  308.   end;
  309. end;
  310.  
  311. {------------------------- TDocument Implementation ---------------------}
  312. constructor TDocument.Init(AParent: PWindowsObject; AFileName: PChar);
  313. begin
  314.   TBaseMDIChildWindow.Init(AParent, AFileName);
  315.   IsNewFile := True;
  316.   Changed := False;
  317.   if AFileName = nil then
  318.     FileName := nil
  319.   else
  320.     FileName := StrNew(AFileName);
  321. end;
  322.  
  323. constructor TDocument.Load(var S: TStream);
  324. begin
  325.   TBaseMDIChildWindow.Load(S);
  326.   FileName := S.StrRead;
  327.   IsNewFile := FileName = nil;
  328. end;
  329.  
  330. destructor TDocument.Done;
  331. begin
  332.   StrDispose(FileName);
  333.   TBaseMDIChildWindow.Done;
  334. end;
  335.  
  336. function TDocument.CanClear: Boolean;
  337. var
  338.   S: array[0..fsPathName+27] of Char;
  339.   P: PChar;
  340.   Rslt: Integer;
  341. begin
  342.   CanClear := True;
  343.   if IsModified then
  344.   begin
  345.     if FileName = nil then StrCopy(S, 'Untitled file has changed. Save?')
  346.     else
  347.     begin
  348.       P := FileName;
  349.       WVSPrintF(S, 'File "%s" has changed.  Save?', P);
  350.     end;
  351.     Rslt := MessageBox(HWindow, S, 'File Changed',
  352.                mb_YesNoCancel or mb_IconQuestion);
  353.     if Rslt = id_Yes then CanClear := Save
  354.     else CanClear := Rslt <> id_Cancel;
  355.   end;
  356. end;
  357.  
  358. function TDocument.CanClose: Boolean;
  359. begin
  360.   CanClose := CanClear;
  361. end;
  362.  
  363. procedure TDocument.ClearWindow;
  364. begin
  365. end;
  366.  
  367. procedure TDocument.ClearModify;
  368. begin
  369. end;
  370.  
  371. procedure TDocument.CMFileSave(var Msg: TMessage);
  372. begin
  373.   Save;
  374. end;
  375.  
  376. procedure TDocument.CMFileSaveAs(var Msg: TMessage);
  377. begin
  378.   SaveAs;
  379. end;
  380.  
  381. function TDocument.GetTitlePrefix: PChar;
  382. begin
  383.   GetTitlePrefix := nil;
  384. end;
  385.  
  386. function TDocument.IsModified: Boolean;
  387. begin
  388.   IsModified := Changed;
  389. end;
  390.  
  391. procedure TDocument.Read;
  392. begin
  393.   IsNewFile := False;
  394. end;
  395.  
  396. function TDocument.Save: Boolean;
  397. begin
  398.   Save := True;
  399.   if IsModified then
  400.     if IsNewFile then Save := SaveAs
  401.     else Write;
  402. end;
  403.  
  404. function TDocument.SaveAs: Boolean;
  405. var
  406.   TmpName: array[0..fsPathName] of Char;
  407. begin
  408.   SaveAs := False;
  409.   if FileName <> nil then StrCopy(TmpName, FileName)
  410.   else TmpName[0] := #0;
  411.   if Application^.ExecDialog(New(PFileDialog,
  412.     Init(@Self, PChar(sd_FileSave), TmpName))) = id_Ok then
  413.   begin
  414.     SetFileName(TmpName);
  415.     Write;
  416.     SaveAs := True;
  417.   end;
  418. end;
  419.  
  420. procedure TDocument.SetFileName(AFileName: PChar);
  421. var
  422.   NewCaption: array[0..80] of Char;
  423. begin
  424.   if FileName <> AFileName then
  425.   begin
  426.     if FileName <> nil then
  427.       StrDispose(FileName);
  428.     FileName := StrNew(AFileName);
  429.   end;
  430.  
  431.   StrCopy(NewCaption, GetTitlePrefix);
  432.   if FileName = nil then
  433.     StrLCat(NewCaption,'(Untitled)',SizeOf(NewCaption) - StrLen(NewCaption))
  434.   else
  435.     StrLCat(NewCaption, AFileName, SizeOf(NewCaption) - StrLen(NewCaption));
  436.   SetWindowText(HWindow, NewCaption);
  437. end;
  438.  
  439. procedure TDocument.SetupWindow;
  440. begin
  441.   TBaseMDIChildWindow.SetupWindow;
  442.   SetFileName(FileName);
  443.   if FileName <> nil then Read;
  444. end;
  445.  
  446. procedure TDocument.Store(var S: TStream);
  447. begin
  448.   TBaseMDIChildWindow.Store(S);
  449.   S.StrWrite(FileName);
  450. end;
  451.  
  452. procedure TDocument.Write;
  453. begin
  454.   Changed := False;
  455. end;
  456.  
  457. {------------------------- TEditWindow Implementation ---------------------}
  458.  
  459. constructor TEditWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  460. var
  461.   Temp: array [0..50] of Char;
  462. begin
  463.   TDocument.Init(AParent, ATitle);
  464.   Editor := New(PEdit, Init(@Self, 200, nil, 0, 0, 0, 0, 0, True));
  465.   with Editor^.Attr do
  466.     Style := Style or es_NoHideSel;
  467.   Inc(OpenEditWindows);
  468. end;
  469.  
  470. constructor TEditWindow.Load(var S: TStream);
  471. begin
  472.   TDocument.Load(S);
  473.   GetChildPtr(S, Editor);
  474. end;
  475.  
  476. destructor TEditWindow.Done;
  477. begin
  478.   TDocument.Done;
  479.   Dec(OpenEditWindows);
  480.   if OpenEditWindows = 0 then
  481.     SetEditPopup(mf_Disabled or mf_Grayed);
  482. end;
  483.  
  484. procedure TEditWindow.ClearModify;
  485. begin
  486.   Editor^.ClearModify;
  487. end;
  488.  
  489. procedure TEditWindow.ClearWindow;
  490. begin
  491.   Editor^.Clear;
  492. end;
  493.  
  494. function TEditWindow.GetTitlePrefix: PChar;
  495. begin
  496.   GetTitlePrefix := 'Text: ';
  497. end;
  498.  
  499. function TEditWindow.IsModified: Boolean;
  500. begin
  501.   IsModified := Editor^.IsModified;
  502. end;
  503.  
  504. procedure TEditWindow.Read;
  505. const
  506.   BufferSize = 1024;
  507. var
  508.   CharsToRead: LongInt;
  509.   BlockSize: Integer;
  510.   AStream: PDosStream;
  511.   ABuffer: PChar;
  512. begin
  513.   TDocument.Read;
  514.   AStream := New(PDosStream, Init(FileName, stOpen));
  515.   ABuffer := MemAlloc(BufferSize + 1);
  516.   CharsToRead := AStream^.GetSize;
  517.   if ABuffer <> nil then
  518.   begin
  519.     Editor^.Clear;
  520.     while CharsToRead > 0 do
  521.     begin
  522.       if CharsToRead > BufferSize then BlockSize := BufferSize
  523.       else BlockSize := CharsToRead;
  524.       AStream^.Read(ABuffer^, BlockSize);
  525.       ABuffer[BlockSize] := Char(0);
  526.       Editor^.Insert(ABuffer);
  527.       CharsToRead := CharsToRead - BlockSize;
  528.     end;
  529.     IsNewFile := False;
  530.     Editor^.ClearModify;
  531.     Editor^.SetSelection(0, 0);
  532.     FreeMem(ABuffer, BufferSize + 1);
  533.   end;
  534.   Dispose(AStream, Done);
  535. end;
  536.  
  537. procedure TEditWindow.Store(var S: TStream);
  538. begin
  539.   TDocument.Store(S);
  540.   PutChildPtr(S, Editor);
  541. end;
  542.  
  543. procedure TEditWindow.WMSetFocus(var Msg: TMessage);
  544. begin
  545.   SetFocus(Editor^.HWindow);
  546. end;
  547.  
  548. procedure TEditWindow.WMSize(var Msg: TMessage);
  549. begin
  550.   TDocument.WMSize(Msg);
  551.   SetWindowPos(Editor^.HWindow, 0, -1, -1, Msg.LParamLo+2, Msg.LParamHi+2,
  552.     swp_NoZOrder);
  553. end;
  554.  
  555. procedure TEditWindow.Write;
  556. const
  557.   BufferSize = 1024;
  558. var
  559.   CharsToWrite, CharsWritten: LongInt;
  560.   BlockSize: Integer;
  561.   AStream: PDosStream;
  562.   ABuffer: pointer;
  563.   NumLines: Integer;
  564. begin
  565.   TDocument.Write;
  566.   NumLines := Editor^.GetNumLines;
  567.   CharsToWrite := Editor^.GetLineIndex(NumLines-1) +
  568.     Editor^.GetLineLength(NumLines-1);
  569.   AStream := New(PDosStream, Init(FileName, stCreate));
  570.   ABuffer := MemAlloc(BufferSize + 1);
  571.   CharsWritten := 0;
  572.   if ABuffer <> nil then
  573.   begin
  574.     while CharsWritten < CharsToWrite do
  575.     begin
  576.       if CharsToWrite - CharsWritten > BufferSize then
  577.         BlockSize := BufferSize
  578.       else BlockSize := CharsToWrite - CharsWritten;
  579.       Editor^.GetSubText(ABuffer, CharsWritten, CharsWritten + BlockSize);
  580.       AStream^.Write(ABuffer^, BlockSize);
  581.       CharsWritten := CharsWritten + BlockSize;
  582.     end;
  583.     Editor^.ClearModify;
  584.     FreeMem(ABuffer, BufferSize + 1);
  585.   end;
  586.  
  587.   Dispose(AStream, Done);
  588. end;
  589.  
  590. {------------------------- TGraphObject Implementation ---------------------}
  591.  
  592. constructor TGraphObject.Init(R: TRect; AColor: TColorRef);
  593. begin
  594.   TObject.Init;
  595.   TheColor := AColor;
  596.   Assign(R);
  597. end;
  598.  
  599. constructor TGraphObject.Load(var S: TStream);
  600. begin
  601.   TObject.Init;
  602.   S.Read(X1, SizeOf(X1));
  603.   S.Read(X2, SizeOf(X2));
  604.   S.Read(Y1, SizeOf(Y1));
  605.   S.Read(Y2, SizeOf(Y2));
  606.   S.Read(TheColor, SizeOf(TheColor));
  607. end;
  608.  
  609. procedure TGraphObject.Assign(R: TRect);
  610. begin
  611.   with R do
  612.   begin
  613.     X1 := Left;
  614.     X2 := Right;
  615.     Y1 := Top;
  616.     Y2 := Bottom;
  617.   end;
  618. end;
  619.  
  620. procedure TGraphObject.Draw(HandleDC: HDC);
  621. begin
  622.   ThePen := CreatePen(ps_Solid, 1, TheColor);
  623.   OldPen := SelectObject(HandleDC, ThePen);
  624. end;
  625.  
  626. procedure TGraphObject.DrawRect(HandleDC: HDC; R: TRect);
  627. begin
  628.   with R do
  629.     SetRect(R, Min(Right, Left), Min(Bottom, Top),
  630.       Max(Right, Left), Max(Top, Bottom));
  631.   Assign(R);
  632.   Draw(HandleDC);
  633. end;
  634.  
  635. procedure TGraphObject.EndDraw(HandleDC: HDC);
  636. begin
  637.   DeleteObject(SelectObject(HandleDC, OldPen));
  638. end;
  639.  
  640.  
  641. procedure TGraphObject.Store(var S: TStream);
  642. begin
  643.   S.Write(X1, SizeOf(X1));
  644.   S.Write(X2, SizeOf(X2));
  645.   S.Write(Y1, SizeOf(Y1));
  646.   S.Write(Y2, SizeOf(Y2));
  647.   S.Write(TheColor, SizeOf(TheColor));
  648. end;
  649.  
  650. {------------------ TRectangle, TCircle Implementations ---------------}
  651.  
  652. procedure TRectangle.Draw(HandleDC: HDC);
  653. begin
  654.   TGraphObject.Draw(HandleDC);
  655.   Rectangle(HandleDC, X1, Y1, X2, Y2);
  656.   EndDraw(HandleDC);
  657. end;
  658.  
  659. procedure TCircle.Draw(HandleDC: HDC);
  660. begin
  661.   TGraphObject.Draw(HandleDC);
  662.   Ellipse(HandleDC, X1, Y1, X2, Y2);
  663.   EndDraw(HandleDC);
  664. end;
  665.  
  666. {------------------------ TGraphWindow Implementation ------------------}
  667.  
  668. constructor TGraphWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  669. begin
  670.   TDocument.Init(AParent, ATitle);
  671.   ButtonDown := False;
  672.   MenuShape := ShapeRectangle;
  673.   MenuColor := RGB(255, 0, 0);
  674.   New(TheShapes, Init(5, 5));
  675. end;
  676.  
  677. destructor TGraphWindow.Done;
  678. begin
  679.   TDocument.Done;
  680.   Dispose(TheShapes, Done);
  681. end;
  682.  
  683. procedure TGraphWindow.Clear;
  684. begin
  685.   TheShapes^.FreeAll;
  686.   InvalidateRect(HWindow, nil, True);
  687.   UpdateWindow(HWindow);
  688. end;
  689.  
  690. procedure TGraphWindow.CMBlue(var Msg: TMessage);
  691. begin
  692.   MenuColor := RGB(0, 0, 255);
  693. end;
  694.  
  695. procedure TGraphWindow.CMCircle(var Msg: TMessage);
  696. begin
  697.   MenuShape := ShapeCircle;
  698. end;
  699.  
  700. procedure TGraphWindow.CMClear(var Msg: TMessage);
  701. begin
  702.   Clear;
  703. end;
  704.  
  705. procedure TGraphWindow.CMGreen(var Msg: TMessage);
  706. begin
  707.   MenuColor := RGB(0, 255, 0);
  708. end;
  709.  
  710. procedure TGraphWindow.CMRectangle(var Msg: TMessage);
  711. begin
  712.   MenuShape := ShapeRectangle;
  713. end;
  714.  
  715. procedure TGraphWindow.CMRed(var Msg: TMessage);
  716. begin
  717.   MenuColor := RGB(255, 0, 0);
  718. end;
  719.  
  720. function TGraphWindow.GetPopupMenu: HMenu;
  721. begin
  722.   GetPopupMenu := LoadMenu(HInstance, MakeIntResource(1001));
  723. end;
  724.  
  725. function TGraphWindow.GetPopupTitle: PChar;
  726. begin
  727.   GetPopupTitle:= 'Graph';
  728. end;
  729.  
  730. function TGraphWindow.GetTitlePrefix: PChar;
  731. begin
  732.   GetTitlePrefix := 'Graph: ';
  733. end;
  734.  
  735. procedure TGraphWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  736.  
  737.   procedure DoPaint(GraphObject: PGraphObject); far;
  738.   begin
  739.     GraphObject^.Draw(PaintDC);
  740.   end;
  741.  
  742. begin
  743.   TheShapes^.ForEach(@DoPaint);
  744. end;
  745.  
  746. procedure TGraphWindow.Read;
  747. var
  748.   AStream: PDosStream;
  749.   NewShapes: PCollection;
  750. begin
  751.   TDocument.Read;
  752.   AStream := New(PDosStream, Init(FileName, stOpenRead));
  753.   NewShapes := PCollection(AStream^.Get);
  754.   if AStream^.Status <> 0 then
  755.     Status := ste_InvalidGraphFileMsg
  756.   else
  757.   begin
  758.     if TheShapes <> nil then
  759.       Dispose(TheShapes, Done);
  760.     TheShapes := NewShapes;
  761.   end;
  762.   Dispose(AStream, Done);
  763. end;
  764.  
  765. procedure TGraphWindow.WMLButtonDown(var Msg: TMessage);
  766. begin
  767.   if not ButtonDown then
  768.   begin
  769.     ButtonDown := True;
  770.     Changed := True;
  771.     SetCapture(hWindow);
  772.     HandleDC := GetDC(hWindow);
  773.     OldROP := SetROP2(HandleDC, r2_NotXORPen);
  774.     with Msg do
  775.       SetRect(Rect, LParamLo, LParamHi, LParamLo, LParamHi);
  776.     case MenuShape of
  777.       ShapeRectangle:  CurrentShape := New(PRectangle, Init(Rect, MenuColor));
  778.       ShapeCircle: CurrentShape := New(PCircle, Init(Rect, MenuColor));
  779.     end;
  780.   end;
  781. end;
  782.  
  783. procedure TGraphWindow.WMLButtonUp(var Msg: TMessage);
  784. begin
  785.   if ButtonDown then
  786.   begin
  787.     ReleaseCapture;
  788.     with Msg do
  789.     begin
  790.       SetRect(Rect, Min(LParamLo, Rect.Left), Min(LParamHi, Rect.Top),
  791.         Max(LParamLo, Rect.Left), Max(LParamHi, Rect.Top));
  792.       SetROP2(HandleDC, OldROP);
  793.       CurrentShape^.Assign(Rect);
  794.       CurrentShape^.Draw(HandleDC);
  795.     end;
  796.     ReleaseDC(HWindow,HandleDC);
  797.     TheShapes^.Insert(CurrentShape);
  798.     ButtonDown := False;
  799.   end;
  800. end;
  801.  
  802. procedure TGraphWindow.WMMouseMove(var Msg: TMessage);
  803. begin
  804.   if ButtonDown then
  805.   with Msg do
  806.   begin
  807.     CurrentShape^.DrawRect(HandleDC, Rect);
  808.     SetRect(Rect, Rect.Left, Rect.Top,
  809.       LParamLo, LParamHi);
  810.     CurrentShape^.DrawRect(HandleDC, Rect);
  811.   end;
  812. end;
  813.  
  814. procedure TGraphWindow.Write;
  815. var
  816.   AStream: PDosStream;
  817. begin
  818.   TDocument.Write;
  819.   AStream := New(PDosStream, Init(FileName, stCreate));
  820.   AStream^.Put(TheShapes);
  821.   Dispose(AStream, Done);
  822. end;
  823.  
  824. {----------------------- TPointCollection Implementation -----------------}
  825.  
  826. destructor TPointCollection.Done;
  827.  
  828.   procedure GoodBye(Point: PPoint); far;
  829.   begin
  830.     Dispose(Point);
  831.   end;
  832.  
  833. begin
  834.   ForEach(@GoodBye);
  835.   DeleteAll;
  836.   TCollection.Done;
  837. end;
  838.  
  839. function TPointCollection.GetItem(var S: TStream): Pointer;
  840. var
  841.   P: PPoint;
  842. begin
  843.   New(P);
  844.   with P^ do
  845.   begin
  846.     S.Read(X, SizeOf(X));
  847.     S.Read(Y, SizeOf(Y));
  848.   end;
  849.   GetItem := P;
  850. end;
  851.  
  852. procedure TPointCollection.PutItem(var S: TStream; Item: Pointer);
  853. begin
  854.   with PPoint(Item)^ do
  855.   begin
  856.     S.Write(X, SizeOf(X));
  857.     S.Write(Y, SizeOf(Y));
  858.   end;
  859. end;
  860.  
  861. {---------------- TLine Implementation -------------------}
  862.  
  863. constructor TLine.Init(AColor: TColorRef; AThickness: Byte);
  864. begin
  865.   TObject.Init;
  866.   LineColor := AColor;
  867.   LineThickness := AThickness;
  868.   New(PointCollection, Init(100, 50));
  869. end;
  870.  
  871. constructor TLine.Load(var S: TStream);
  872. begin
  873.   S.Read(X, SizeOf(X));
  874.   S.Read(Y, SizeOf(Y));
  875.   S.Read(LineColor, SizeOf(LineColor));
  876.   S.Read(LineThickness, SizeOf(LineThickness));
  877.   PointCollection := PPointCollection(S.Get);
  878. end;
  879.  
  880. destructor TLine.Done;
  881. begin
  882.   TObject.Done;
  883.   Dispose(PointCollection, Done);
  884. end;
  885.  
  886. procedure TLine.Store(var S: TStream);
  887. begin
  888.   S.Write(X, SizeOf(X));
  889.   S.Write(Y, SizeOf(Y));
  890.   S.Write(LineColor, SizeOf(LineColor));
  891.   S.Write(LineThickness, SizeOf(LineThickness));
  892.   S.Put(PointCollection);
  893. end;
  894.  
  895. {---------------------- TScribbleWindow Implementation ---------------}
  896.  
  897. constructor TScribbleWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  898. begin
  899.   TDocument.Init(aParent, ATitle);
  900.   ButtonDown := False;
  901.   MenuColor := RGB(255, 0, 0);
  902.   MenuThickness := 3;
  903.   New(LineCollection, Init(5, 5));
  904. end;
  905.  
  906. constructor TScribbleWindow.Load(var S: TStream);
  907. begin
  908.   TDocument.Load(S);
  909.   LineCollection := PCollection(S.Get);
  910. end;
  911.  
  912. destructor TScribbleWindow.Done;
  913. begin
  914.   TDocument.Done;
  915.   Dispose(LineCollection, Done);
  916. end;
  917.  
  918. procedure TScribbleWindow.Clear;
  919. begin
  920.   LineCollection^.FreeAll;
  921.   InvalidateRect(HWindow, nil, True);
  922.   UpdateWindow(HWindow);
  923. end;
  924.  
  925. procedure TScribbleWindow.CMBlue(var Msg: TMessage);
  926. begin
  927.   MenuColor := RGB(0, 0, 255);
  928. end;
  929.  
  930. procedure TScribbleWindow.CMClear(var Msg: TMessage);
  931. begin
  932.   Clear;
  933. end;
  934.  
  935. procedure TScribbleWindow.CMGreen(var Msg: TMessage);
  936. begin
  937.   MenuColor := RGB(0, 255, 0);
  938. end;
  939.  
  940. procedure TScribbleWindow.CMNormal(var Msg: TMessage);
  941. begin
  942.   MenuThickness := 3;
  943. end;
  944.  
  945. procedure TScribbleWindow.CMRed(var Msg: TMessage);
  946. begin
  947.   MenuColor := RGB(255, 0, 0);
  948. end;
  949.  
  950. procedure TScribbleWindow.CMThick(var Msg: TMessage);
  951. begin
  952.   MenuThickness := 5;
  953. end;
  954.  
  955. procedure TScribbleWindow.CMThin(var Msg: TMessage);
  956. begin
  957.   MenuThickness := 1;
  958. end;
  959.  
  960. function TScribbleWindow.GetPopupMenu: HMenu;
  961. begin
  962.   GetPopupMenu := LoadMenu(HInstance, MakeIntResource(1000));
  963. end;
  964.  
  965. function TScribbleWindow.GetPopupTitle: PChar;
  966. begin
  967.   GetPopupTitle:= 'Scribble';
  968. end;
  969.  
  970. function TScribbleWindow.GetTitlePrefix: PChar;
  971. begin
  972.   GetTitlePrefix := 'Scribble: ';
  973. end;
  974.  
  975. procedure TScribbleWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  976.  
  977.   procedure DrawLine(Line: PLine); far;
  978.  
  979.     procedure DrawSegments(Segment: PPoint); far;
  980.     begin
  981.       LineTo(PaintDC, Segment^.X, Segment^.Y);
  982.     end;
  983.  
  984.   begin
  985.     with Line^ do
  986.     begin
  987.       OldPen := SelectObject(PaintDC, CreatePen(ps_Solid, LineThickness,
  988.         LineColor));
  989.       MoveTo(PaintDC, X, Y);
  990.       PointCollection^.ForEach(@DrawSegments);
  991.       DeleteObject(SelectObject(PaintDC, OldPen));
  992.     end;
  993.   end;
  994.  
  995. begin
  996.   LineCollection^.ForEach(@DrawLine);
  997. end;
  998.  
  999. procedure TScribbleWindow.Read;
  1000. var
  1001.   AStream: PDosStream;
  1002.   NewLines: PCollection;
  1003. begin
  1004.   TDocument.Read;
  1005.   AStream := New(PDosStream, Init(FileName, stOpenRead));
  1006.   NewLines := PCollection(AStream^.Get);
  1007.   if AStream^.Status <> 0 then
  1008.     Status := ste_InvalidScribbleFileMsg
  1009.   else
  1010.   begin
  1011.     if LineCollection <> nil then
  1012.       Dispose(LineCollection, Done);
  1013.     LineCollection := NewLines;
  1014.   end;
  1015.   Dispose(AStream, Done);
  1016. end;
  1017.  
  1018. procedure TScribbleWindow.Store(var S: TStream);
  1019. begin
  1020.   TDocument.Store(S);
  1021.   S.Put(LineCollection);
  1022. end;
  1023.  
  1024. procedure TScribbleWindow.WMLButtonDown(var Msg: TMessage);
  1025. begin
  1026.   if not ButtonDown then
  1027.   begin
  1028.     ButtonDown := True;
  1029.     Changed := True;
  1030.     SetCapture(HWindow);
  1031.     HandleDC := GetDC(HWindow);
  1032.     OldPen := SelectObject(HandleDC, CreatePen(ps_Solid, MenuThickness,
  1033.       MenuColor));
  1034.     MoveTo(HandleDC, Msg.LParamLo, Msg.LParamHi);
  1035.     New(CurrentLine, Init(MenuColor, MenuThickness));
  1036.     CurrentLine^.X := Msg.LParamLo;
  1037.     CurrentLine^.Y := Msg.LParamHi;
  1038.   end;
  1039. end;
  1040.  
  1041. procedure TScribbleWindow.WMLButtonUp(var Msg: TMessage);
  1042. begin
  1043.   if ButtonDown then
  1044.   begin
  1045.     ReleaseCapture;
  1046.     DeleteObject(SelectObject(HandleDC, OldPen));
  1047.     ReleaseDC(HWindow,HandleDC);
  1048.     ButtonDown := False;
  1049.     LineCollection^.Insert(CurrentLine);
  1050.   end;
  1051. end;
  1052.  
  1053. procedure TScribbleWindow.WMMouseMove(var Msg: TMessage);
  1054. var
  1055.   APoint: PPoint;
  1056. begin
  1057.   if ButtonDown then
  1058.   begin
  1059.     LineTo(HandleDC, Msg.LParamLo, Msg.LParamHi);
  1060.     New(APoint);
  1061.     APoint^.X := Msg.LParamLo;
  1062.     APoint^.Y := Msg.LParamHi;
  1063.     CurrentLine^.PointCollection^.Insert(APoint);
  1064.   end;
  1065. end;
  1066.  
  1067. procedure TScribbleWindow.Write;
  1068. var
  1069.   AStream: PDosStream;
  1070. begin
  1071.   TDocument.Write;
  1072.   AStream := New(PDosStream, Init(FileName, stCreate));
  1073.   AStream^.Put(LineCollection);
  1074.   Dispose(AStream, Done);
  1075. end;
  1076.  
  1077. {------------------ Stream Registration Records -----------------------}
  1078. const
  1079.   REditWindow: TStreamRec = (
  1080.     ObjType: 80;
  1081.     VmtLink: Ofs(TypeOf(TEditWindow)^);
  1082.     Load:    @TEditWindow.Load;
  1083.     Store:   @TEditWindow.Store);
  1084.  
  1085. const
  1086.   RDocument: TStreamRec = (
  1087.     ObjType: 81;
  1088.     VmtLink: Ofs(TypeOf(TDocument)^);
  1089.     Load:    @TDocument.Load;
  1090.     Store:   @TDocument.Store);
  1091.  
  1092. const
  1093.   RScribbleWindow: TStreamRec = (
  1094.     ObjType: 82;
  1095.     VmtLink: Ofs(TypeOf(TScribbleWindow)^);
  1096.     Load:    @TScribbleWindow.Load;
  1097.     Store:   @TScribbleWindow.Store);
  1098.  
  1099. const
  1100.   RGraphWindow: TStreamRec = (
  1101.     ObjType: 83;
  1102.     VmtLink: Ofs(TypeOf(TGraphWindow)^);
  1103.     Load:    @TGraphWindow.Load;
  1104.     Store:   @TGraphWindow.Store);
  1105.  
  1106. const
  1107.   RPointCollection: TStreamRec = (
  1108.     ObjType: 84;
  1109.     VmtLink: Ofs(TypeOf(TPointCollection)^);
  1110.     Load:    @TPointCollection.Load;
  1111.     Store:   @TPointCollection.Store);
  1112.  
  1113. const
  1114.   RLine: TStreamRec = (
  1115.     ObjType: 85;
  1116.     VmtLink: Ofs(TypeOf(TLine)^);
  1117.     Load:    @TLine.Load;
  1118.     Store:   @TLine.Store);
  1119.  
  1120. const
  1121.   RGraphObject: TStreamRec = (
  1122.     ObjType: 86;
  1123.     VmtLink: Ofs(TypeOf(TGraphObject)^);
  1124.     Load:    @TGraphObject.Load;
  1125.     Store:   @TGraphObject.Store);
  1126.  
  1127. const
  1128.   RRectangle: TStreamRec = (
  1129.     ObjType: 87;
  1130.     VmtLink: Ofs(TypeOf(TRectangle)^);
  1131.     Load:    @TRectangle.Load;
  1132.     Store:   @TRectangle.Store);
  1133. const
  1134.   RCircle: TStreamRec = (
  1135.     ObjType: 88;
  1136.     VmtLink: Ofs(TypeOf(TCircle)^);
  1137.     Load:    @TCircle.Load;
  1138.     Store:   @TCircle.Store);
  1139.  
  1140. begin
  1141.   RegisterWobjects;
  1142.   RegisterType(REditWindow);
  1143.   RegisterType(RDocument);
  1144.   RegisterType(RScribbleWindow);
  1145.   RegisterType(RGraphWindow);
  1146.   RegisterType(RPointCollection);
  1147.   RegisterType(RLine);
  1148.   RegisterType(RGraphObject);
  1149.   RegisterType(RRectangle);
  1150.   RegisterType(RCircle);
  1151. end.
  1152.  
  1153.